package wqh.controller;


import cn.tpson.modbus.core.ModBusDevice;
import cn.tpson.modbus.core.ModBusManager;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import wqh.controller.api.GlobalData;
import wqh.domain.Channel;
import wqh.domain.Device;
import wqh.global.GlobalDevice;
import wqh.global.GlobalTime;
import wqh.pojo.ChannelUpdate;
import wqh.pojo.IPConver;
import wqh.pojo.MapRet;
import wqh.service.ChannelService;
import wqh.service.DeviceService;
import wqh.service.MapPosService;


import javax.servlet.http.HttpServletRequest;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@RestController
@CrossOrigin(origins = "*")
@RequestMapping("/water/device")
public class DeviceJSONController {

    private static org.slf4j.Logger logger = LoggerFactory.getLogger(DeviceJSONController.class);

    @Autowired
    private DeviceService deviceService;

    @Autowired
    private ChannelService channelService;

    @Autowired
    private MapPosService mapPosService;

    @RequestMapping(value = "/getAll", method = RequestMethod.GET)
    public Object getAll()
    {
        List<Device> deviceList = deviceService.findAllRecord();
        for(Device device : deviceList)
        {
            if(GlobalDevice.exist(device.getDevice_ip()))
            {
                device.setOnline((byte)1);
            }
            else
            {
                device.setOnline((byte)0);
            }
        }
        return MapRet.DATA(deviceList);
    }

    @RequestMapping(value = "/getAll2", method = RequestMethod.GET)
    public Object getAll2()
    {
        List<Device> deviceList = deviceService.findAllRecord();
        return MapRet.DATA(deviceList);
    }

    @RequestMapping(value = "/getAll3", method = RequestMethod.GET)
    public Object getAll3()
    {
        List<Device> deviceList = deviceService.findAllRecord();
        List<Map<String,Object>> mapList = new ArrayList<Map<String, Object>>();
        for(Device device : deviceList){
            Map<String,Object> map = new HashMap<String, Object>();
            map.put("id",device.getId());
            map.put("text",device.getDevice_name());
            mapList.add(map);
        }
        return MapRet.DATA(mapList);
    }

    @RequestMapping(value = "/add", method = RequestMethod.POST)
    public Object add(@RequestBody Device device)
    {
        try{
//            if(!IPConver.isValidIp(device.getDevice_ip())) return MapRet.IP_ERROR();
            if(deviceService.findAllByIP(device.getDevice_ip()) != null) return MapRet.SQL_ERROR("IP已存在");
            device.setId(null);
            device.setPicture(null);
            device.setOnline((byte)0);
            deviceService.insertRecord(device);
            GlobalData.clear();
            logger.info("添加水压主机：" + device.toString());
            return MapRet.SQL_INSERT_SUCCESS();
        }catch (Exception e)
        {
            e.printStackTrace();
            logger.error("添加水压主机错误：" + e);
            return MapRet.SQL_INSERT_ERROR();
        }
    }

    @RequestMapping(value = "/update",method = RequestMethod.POST)
    public Object update(@RequestBody Device device)
    {
        if(device.getId() == null) return MapRet.DATA_ERROR("id不存在");
        try {
            Device oldDevice = deviceService.findAllById(device.getId());
            if(oldDevice == null) return MapRet.SQL_ERROR("系统中无此记录");
            if(!IPConver.isValidIp(device.getDevice_ip())) return MapRet.IP_ERROR();
            deviceService.updateDateById(device);

            ChannelUpdate c = new ChannelUpdate(oldDevice.getDevice_name(),oldDevice.getDevice_ip(),device.getDevice_name(),device.getDevice_ip());
            channelService.updateRecord2(c);

            GlobalData.clear();

            logger.info("修改水压主机：" + device.toString());
            return MapRet.SQL_UPDATE_SUCCESS();
        }catch (Exception e)
        {
            e.printStackTrace();
            logger.error("修改水压主机错误：" + e);
            return MapRet.SQL_UPDATE_ERROR();
        }
    }

    @RequestMapping(value = "/update2",method = RequestMethod.POST)
    public Object update2(HttpServletRequest httpServletRequest,
                          @RequestParam(value = "id",required = true) Integer id,
                          @RequestParam(value = "name",required = true) String name,
                          @RequestParam(value = "ip",required = true) String ip,
                          @RequestParam(value = "port",required = true) int port,
                          @RequestParam(value = "detail",required = false,defaultValue = "0") String detail,
                          @RequestParam(value = "file",required = false,defaultValue = "null")MultipartFile file)
    {
        try {
            Device oldDevice = deviceService.findAllById(id);
            if(oldDevice == null) return MapRet.SQL_ERROR("系统中无此记录");
            if(!IPConver.isValidIp(ip)) return MapRet.IP_ERROR();
            Device device = new Device();
            device.setId(id);
            device.setDevice_name(name);
            device.setDevice_ip(ip);
            device.setPort(port);
            device.setDetail(detail);
            if(file != null && !file.isEmpty())
            {
                removePicture(oldDevice,httpServletRequest);
                String localPath = "upload\\picture\\";
                String uploadPath = httpServletRequest.getServletContext().getRealPath("/") + localPath;
                File uploadDir = new File(uploadPath);
                if(!uploadDir.exists())
                {
                    uploadDir.mkdirs();
                }
                String fileName = file.getOriginalFilename();
                if(fileName != null)
                {
                    byte[] bytes = file.getBytes();
                    fileName = System.currentTimeMillis() + fileName;
                    File serverFile = new File(uploadDir.getAbsolutePath() + File.separator + fileName);
                    BufferedOutputStream stream = new BufferedOutputStream(new FileOutputStream(serverFile));
                    stream.write(bytes);
                    stream.close();
                    device.setPicture(localPath + serverFile.getName());
                }
            }
            deviceService.updateDateById(device);
            ChannelUpdate c = new ChannelUpdate(oldDevice.getDevice_name(),oldDevice.getDevice_ip(),device.getDevice_name(),device.getDevice_ip());
            channelService.updateRecord2(c);
            logger.info("修改水压主机2：" + device.toString());
            GlobalData.clear();
            return MapRet.SQL_UPDATE_SUCCESS();
        }catch (Exception e)
        {
            e.printStackTrace();
            logger.error("修改水压主机错误：" + e);
            return MapRet.SQL_UPDATE_ERROR();
        }
    }


    @RequestMapping(value = "/delete",method = RequestMethod.POST)
    public Object delete(HttpServletRequest httpServletRequest,
                         @RequestParam(value = "id",required = true) int id)
    {
        try {
            Device oldDevice = deviceService.findAllById(id);
            if(oldDevice == null) return MapRet.SQL_ERROR("系统中无此记录");
            removePicture(oldDevice,httpServletRequest);
            deviceService.deleteById(id);

            Channel channel = new Channel();
            channel.setName(oldDevice.getDevice_name());
            channel.setIp(channel.getIp());
            channelService.deleteByClass(channel);

            mapPosService.deleteByDeviceId(id);

            try {
                ModBusManager.getInstance().removeDevice(oldDevice.getDevice_ip());
            }catch (Exception e)
            {
                System.out.println("主机没有连接：" + e.toString());
                return MapRet.SUCCESS();
            }
            logger.info("删除水压主机：" + oldDevice.toString());
            GlobalData.clear();
            return MapRet.SQL_DELETE_SUCCESS();
        }catch (Exception e)
        {
            e.printStackTrace();
            logger.error("删除水压主机错误：" + e);
            return MapRet.SQL_DELETE_ERROR();
        }
    }

    @RequestMapping(value = "/uploadPicture",method = RequestMethod.POST)
    public Object uploadPicture(HttpServletRequest httpServletRequest,
                                @RequestParam(value = "file",required = true)MultipartFile file,
                                @RequestParam(value = "id",required = true) int id)
    {
       try {
           Device device = deviceService.findAllById(id);
           if(device == null){
               MapRet.SQL_ERROR("数据不存在");
           }
            else{
               removePicture(device,httpServletRequest);
               String localPath = "upload\\picture\\";
               String uploadPath = httpServletRequest.getServletContext().getRealPath("/") + localPath;
               File uploadDir = new File(uploadPath);
               if(!uploadDir.exists())
               {
                   uploadDir.mkdirs();
               }
               String fileName = file.getOriginalFilename();
               if(fileName != null)
               {
                   byte[] bytes = file.getBytes();
                   fileName = System.currentTimeMillis() + fileName;
                   File serverFile = new File(uploadDir.getAbsolutePath() + File.separator + fileName);
                   BufferedOutputStream stream = new BufferedOutputStream(new FileOutputStream(serverFile));
                   stream.write(bytes);
                   stream.close();
                   Device deviceNew = new Device();
                   deviceNew.setId(id);
                   deviceNew.setPicture(localPath + serverFile.getName());
                   deviceService.updateDateById(deviceNew);
                   logger.info("上传图片：" + deviceNew.toString());
               }
           }
           return MapRet.FILE_UPLOAD_SUCCESS();
       }catch (Exception e){
           e.printStackTrace();
           logger.error("图片上传错误：" + e);
           return MapRet.FILE_UPLOAD_ERROR();
       }
    }

    @RequestMapping(value = "/getStatus",method = RequestMethod.GET)
    public Object getStatus()
    {
        return MapRet.DATA(ModBusManager.getInstance().getStatusMap());
    }

    @RequestMapping(value = "/online",method = RequestMethod.GET)
    public  Object online(@RequestParam(value = "id",required = true) int id)
    {
        try {
            Device device = deviceService.findAllById(id);
            System.out.println(device);
            if(!GlobalDevice.exist(device.getDevice_ip()))
            {
                ModBusDevice modBusDevice = new ModBusDevice(device.getDevice_ip(),device.getPort(), GlobalTime.getTime());
                modBusDevice.setAddress((byte)1);
                ModBusManager.getInstance().addDevice(modBusDevice);
            }
            System.out.println(GlobalDevice.getIpList());
            System.out.println(ModBusManager.getInstance().getStatusMap());
            return MapRet.SUCCESS();
        }catch (Exception e)
        {
            e.printStackTrace();
            logger.error("主机连接异常：" + e);
            return MapRet.DATA_ERROR("连接失败");
        }
    }

    @RequestMapping(value = "/offLine",method = RequestMethod.GET)
    public  Object offLine(@RequestParam(value = "id",required = true) int id)
    {
        try {
            Device device = deviceService.findAllById(id);
            if(GlobalDevice.exist(device.getDevice_ip()))
            {
                ModBusManager.getInstance().removeDevice(device.getDevice_ip());
            }
            return MapRet.SUCCESS();
        }catch (Exception e)
        {
            e.printStackTrace();
            logger.error("主机断开异常：" + e);
            return MapRet.DATA_ERROR("连接失败");
        }
    }

    public void removePicture(Device device,HttpServletRequest httpServletRequest)
    {
        String localPath = "upload\\picture\\";
        String uploadPath = httpServletRequest.getServletContext().getRealPath("/") + localPath;
        if(device.getPicture() != null && device.getPicture().length() != 0 && !device.getPicture().equals("0"))
        {
            String serverPath = uploadPath +device.getPicture();
            File serverFile = new File(serverPath);
            if(serverFile.isFile() && serverFile.exists())
            {
                serverFile.delete();
            }
        }
    }

}
